package grape.common.rest;

import grape.common.rest.security.GrapeJwtAccessTokenConverter;
import grape.common.rest.security.UserDetailsPlaceholderServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.List;
import java.util.Optional;

/**
 * Created by yangwei
 * Created at 2020/1/13 14:19
 */
@Configuration
public class CommonRestSecurityConfig extends WebSecurityConfigurerAdapter {

    //shareJwt.yaml
    @Value("${grape.jwt.secret}")
    private String jwtSecret;
    @Autowired(required = false)
    private List<CommonRestSecurityConfigure> commonRestSecurityConfigureList;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //禁用baisc和form认证
                .httpBasic().disable()
                .formLogin().disable()
                .anonymous().disable()
                .csrf().disable()
                .logout().disable()
                // iframe 同源可访问
                .headers().frameOptions().sameOrigin().httpStrictTransportSecurity().disable().and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        if (commonRestSecurityConfigureList != null) {
            for (CommonRestSecurityConfigure commonRestSecurityConfigure : commonRestSecurityConfigureList) {
                commonRestSecurityConfigure.configure(http);
            }
        }
    }

    @Override
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        if (commonRestSecurityConfigureList != null) {
            for (CommonRestSecurityConfigure commonRestSecurityConfigure : commonRestSecurityConfigureList) {
                commonRestSecurityConfigure.configure(auth,passwordEncoder());
            }
        }else {
            // 添加一个占位实现
            auth.userDetailsService(new UserDetailsService() {
                @Override
                public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                    throw new RuntimeException("你调用了一个占位实现");
                }
            }).passwordEncoder(passwordEncoder()).configure(auth);
        }

    }
    /**
     * 密码加解密处理，用户添加的时候也会用到
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(PasswordEncoder.class)
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * jwt token的生成配置
     *
     * @return
     */
    @Bean
    //public JwtAccessTokenConverter accessTokenConverter() {
    public GrapeJwtAccessTokenConverter accessTokenConverter() {
        GrapeJwtAccessTokenConverter converter = new GrapeJwtAccessTokenConverter();
        converter.setSigningKey(jwtSecret);
        return converter;
    }
}
